package com.intech.android.demo.cms.beans;

import com.intech.android.demo.cms.bo.Category;
import com.intech.android.demo.cms.bo.Group;
import com.intech.android.demo.cms.bo.Region;
import com.intech.android.demo.cms.bo.VideoContent;
import com.intech.android.demo.cms.common.Constants;
import com.intech.android.demo.cms.common.FacesHelper;
import com.intech.android.demo.cms.common.Util;
import com.intech.android.demo.cms.dao.interfaces.VideoContentDAO;
import com.intech.android.demo.cms.decorators.VideoContentDecorator;
import com.intech.android.demo.cms.enums.Mode;
import com.intech.android.demo.cms.validators.DoubleNumberValidator;
import com.intech.android.demo.cms.validators.VideoContentValidator;
import org.apache.log4j.Logger;
import org.apache.myfaces.custom.fileupload.UploadedFileDefaultFileImpl;


import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import com.intech.android.demo.cms.enums.*;

public class VideoContentBean extends BaseBean
{
    private static final Logger log = Logger.getLogger(VideoContentBean.class);

    private String contentId = "69";
    private Integer rowCount;
    private List<VideoContent> videoContentsBOs;
    private List<VideoContentDecorator> videoContents;
    private List<SelectItem> categories;
    private List<SelectItem> groups;
    private List<SelectItem> regions;
    private List<SelectItem> statuses;

    private Status videoContentStatus;
    private String filterStatus;

    private String newVideoContentBudget;
    private String advertiserSite;
    private String newContentName;
    private String newAdvertiserName;
    private String newContentViewingCost;
    private List<Integer> chosenGroups = new ArrayList<Integer>();

    private Integer chosenCategoryId;
    private List<Integer> chosenFilterCategories = new ArrayList<Integer>();

    private List<Integer> chosenRegions = new ArrayList<Integer>();
    private List<Integer> chosenFilterRegions = new ArrayList<Integer>();

    private Status chosenStatus;
    private String description;
    private DoubleNumberValidator paymentValidator;
    private DoubleNumberValidator budgetValidator;
    private String filterByStatus = "all";
    private String filterId;
    private String soundTrack = "way=file:///home/oles/Projects/Intech/android-cms/work/out/SleepAway.mp3";
    private final String SOUND_TRACK_PREFIX = "way=";


    private UploadedFileDefaultFileImpl uploadedFile;
    private String message;
    private String fileName;

    private VideoContent currentVideoContent;
    private String filterName;
    private String filterAdvertiser;

    private Mode mode = Mode.Create;

    private boolean dirty;

    private String uploadedFilePath;

    private Integer rows;

    private String from;

    private String to;

    public VideoContentBean()
    {
        videoContents = new ArrayList<VideoContentDecorator>();
        dirty = true;
        if (Util.isEmpty(videoContentsBOs))
        {
            videoContentsBOs = getVideoContentDAO().getAll();
            dirty = false;
        }
    }

    public void restrictRows(ActionEvent event)
    {
        if (!Util.isEmpty(rows))
        {
            videoContentsBOs = getVideoContentDAO().getAll(rows);
            dirty = false;
        }
    }

    public void checkAllCategories(ActionEvent event)
    {
        chosenFilterCategories = new ArrayList<Integer>();
        for (SelectItem item : categories)
        {
            chosenFilterCategories.add((Integer) item.getValue());
        }
        int a = chosenFilterCategories.size();
    }

    public void clearAllCategories(ActionEvent event)
    {
        chosenFilterCategories = new ArrayList<Integer>();
    }

    public void clearAllRegions(ActionEvent event)
    {
        chosenRegions = new ArrayList<Integer>();
    }

    public void checkAllRegions(ActionEvent event)
    {
        chosenRegions = new ArrayList<Integer>();
        for (SelectItem item : regions)
        {
            chosenRegions.add((Integer) item.getValue());
        }
    }

    public void clearAllGroups(ActionEvent event)
    {
        chosenGroups = new ArrayList<Integer>();
    }

    public void checkAllGroups(ActionEvent event)
    {
        chosenGroups = new ArrayList<Integer>();
        for (SelectItem item : groups)
        {
            chosenGroups.add((Integer) item.getValue());
        }
    }


    public void filterByStatus(ValueChangeEvent event)
    {
        chosenStatus = (Status) event.getNewValue();

    }

    public void processFile(ActionEvent event)
    {
        try
        {
            fileName = uploadedFile.getName();
            byte[] b = uploadedFile.getBytes();
            uploadedFilePath = Constants.Settings.UPLOADED_DIR + fileName;
            FileOutputStream fos = new FileOutputStream(uploadedFilePath);
            fos.write(b);
            fos.flush();
            fos.close();
            message = FacesHelper.getBundleMessage("file_saved_message", new Object[]{fileName, uploadedFilePath});

        }
        catch (Exception e)
        {
            log.error(e.getMessage(), e);
        }
    }


    public boolean saveNewVideoContent()
    {
        VideoContentValidator validator = new VideoContentValidator(newVideoContentBudget, newContentViewingCost);
        validator.check();
        if (validator.isValid())
        {
            Category chosenCategory = getCategoryDAO().getById(chosenCategoryId);
            List<Region> chosenRegions = getRegionDAO().getListById(this.chosenRegions);
            List<Group> chosenGroups = getGroupDAO().getListById(this.chosenGroups);

            if (mode == Mode.Create)
            {
                currentVideoContent = BeanUtil.createVideoContent(newContentName, description, newVideoContentBudget, newContentViewingCost, chosenCategory, new HashSet<Group>(chosenGroups), new HashSet<Region>(chosenRegions), newAdvertiserName, advertiserSite);
            }
            else if (mode == Mode.Edit)
            {
                currentVideoContent = BeanUtil.updateVideoContent(currentVideoContent, newContentName, description, newVideoContentBudget, newContentViewingCost, chosenCategory, new HashSet<Group>(chosenGroups), new HashSet<Region>(chosenRegions), newAdvertiserName, advertiserSite);
            }

            getVideoContentDAO().save(currentVideoContent);
            dirty = true;
            return true;
        }
        message = validator.getMessage();
        return false;
    }

    public UploadedFileDefaultFileImpl getUploadedFile()
    {
        return uploadedFile;
    }

    public void setUploadedFile(UploadedFileDefaultFileImpl uploadedFile)
    {
        this.uploadedFile = uploadedFile;
    }

    public String getMessage()
    {
        return message;
    }

    public void setMessage(String message)
    {
        this.message = message;
    }

    public String getFileName()
    {
        return fileName;
    }

    public void setFileName(String fileName)
    {
        this.fileName = fileName;
    }


    public String toAddVideoContent()
    {
        mode = Mode.Create;
        clearFields();
        chosenGroups = new ArrayList<Integer>();
        chosenRegions = new ArrayList<Integer>();

        return Constants.Navigation.ADD_VIDEO_CONTENT_LINK;
    }

    private void clearFields()
    {
        contentId = "69";
        chosenGroups = new ArrayList<Integer>();
        chosenRegions = new ArrayList<Integer>();
        chosenStatus = null;
        chosenCategoryId = null;
        newVideoContentBudget = null;
        advertiserSite = null;
        newContentName = null;
        newAdvertiserName = null;
        newContentViewingCost = null;
        description = null;
    }

    private void restoreFields()
    {
        clearFields();
        for (Group group : currentVideoContent.getGroups())
        {
            chosenGroups.add(group.getId());
        }
        for (Region region : currentVideoContent.getRegions())
        {
            chosenRegions.add(region.getId());
        }
        contentId = currentVideoContent.getId().toString();
        chosenCategoryId = currentVideoContent.getCategory().getId();
        newVideoContentBudget = currentVideoContent.getBudget().toString();
        advertiserSite = currentVideoContent.getAdvertiserSite();
        newContentName = currentVideoContent.getName();
        newAdvertiserName = currentVideoContent.getAdvertiser();
        newContentViewingCost = currentVideoContent.getPayment().toString();
        description = currentVideoContent.getDescription();
    }

    public String toVideoContent()
    {
        if (saveNewVideoContent())
        {
            return backToVideoContent();
        }
        return Constants.Navigation.ADD_VIDEO_CONTENT_LINK;
    }

    public String backToVideoContent()
    {
        return Constants.Navigation.VIDEO_CONTENT_LINK;
    }


    public List<SelectItem> getStatuses()
    {
        statuses = new ArrayList<SelectItem>();
        statuses.add(new SelectItem(Status.All, Status.All.getMessage()));
        statuses.add(new SelectItem(Status.Active, Status.Active.getMessage()));
        statuses.add(new SelectItem(Status.Inactive, Status.Inactive.getMessage()));
        return statuses;
    }

    public void setStatuses(List<SelectItem> statuses)
    {
        this.statuses = statuses;
    }


    public Integer getChosenCategoryId()
    {
        return chosenCategoryId;
    }

    public void setChosenCategoryId(Integer chosenCategoryId)
    {
        this.chosenCategoryId = chosenCategoryId;
    }

    public List<VideoContentDecorator> getVideoContents()
    {


        if (dirty)
        {
            videoContents = new ArrayList<VideoContentDecorator>();
            videoContentsBOs = getVideoContentDAO().getAll();
            for (VideoContent videoContent : videoContentsBOs)
            {
                videoContents.add(new VideoContentDecorator(videoContent));
            }
            dirty = false;
        }
        else
        {
            videoContents = new ArrayList<VideoContentDecorator>();
            for (VideoContent videoContent : videoContentsBOs)
            {
                videoContents.add(new VideoContentDecorator(videoContent));
            }
        }

        return videoContents;
    }

    public void findVideoContentByGroupsRegionsStatusBudget(ActionEvent actionEvent)
    {
        videoContentsBOs = new ArrayList<VideoContent>();

        Double chosenFrom = null;
        Double chosenTo = null;
        try
        {
            chosenFrom = Double.parseDouble(from);
            chosenTo = Double.parseDouble(to);
        }
        catch (Exception e)
        {
            //nothing
        }

        videoContentsBOs = getVideoContentDAO().findVideoContents(chosenFilterRegions, chosenFilterCategories, chosenStatus, chosenFrom, chosenTo);
    }

    public void findVideoContentById(ActionEvent actionEvent)
    {
        videoContentsBOs = new ArrayList<VideoContent>();
        VideoContent foundVideoContent = getVideoContentDAO().getById(Integer.parseInt(filterId));
        if (foundVideoContent != null)
        {
            videoContentsBOs.add(foundVideoContent);
        }
    }

    public void findVideoContentByName(ActionEvent actionEvent)
    {
        videoContentsBOs = getVideoContentDAO().findVideoContentsByName(filterName);
    }

    public void findVideoContentByAdvertiser(ActionEvent actionEvent)
    {
        videoContentsBOs = getVideoContentDAO().findVideoContentsByAdvertiser(filterAdvertiser);
    }

    public String getVideoContentStatus()
    {
        String message = "";
        if (newVideoContentBudget != null)
        {
            videoContentStatus = getStatusByBudget(newVideoContentBudget);
        }
        if (videoContentStatus != null)
        {
            message = videoContentStatus.getMessage();
        }
        return message;
    }

    public Status getStatusByBudget(String budget)
    {
        Status status = Status.Inactive;
        try
        {
            Double parsedBudget = Double.parseDouble(budget);
            if (parsedBudget > Constants.Logic.MIN_BUDGET)
            {
                status = Status.Active;
            }
            else
            {
                status = Status.Inactive;
            }
        }
        catch (NumberFormatException e)
        {
            //            status = INACTIVE_STATUS;
        }
        return status;
    }


    public String getNewVideoContentBudget()
    {
        return newVideoContentBudget;
    }

    public void setNewVideoContentBudget(String newVideoContentBudget)
    {
        this.newVideoContentBudget = newVideoContentBudget;
    }

    public String getAdvertiserSite()
    {
        return advertiserSite;
    }

    public void setAdvertiserSite(String advertiserSite)
    {
        this.advertiserSite = advertiserSite;
    }

    public String getNewContentName()
    {
        return newContentName;
    }

    public void setNewContentName(String newContentName)
    {
        this.newContentName = newContentName;
    }

    public String getNewAdvertiserName()
    {
        return newAdvertiserName;
    }

    public void setNewAdvertiserName(String newAdvertiserName)
    {
        this.newAdvertiserName = newAdvertiserName;
    }

    public List<SelectItem> getGroups()
    {
        if (Util.isEmpty(groups))
        {
            groups = new ArrayList<SelectItem>();
            List<Group> allGroups = getGroupDAO().getAll();
            for (Group group : allGroups)
            {
                SelectItem selectItem = new SelectItem(group.getId(), group.getName());
                groups.add(selectItem);
            }
        }
        return groups;
    }

    public String editVideoContent()
    {
        mode = Mode.Edit;

        Integer video_id = FacesHelper.getParameterAsInteger("edit_video_id");
        if (video_id == null)
        {
            log.error("video id is null");
            return Constants.Navigation.VIDEO_CONTENT_LINK;
        }
        currentVideoContent = getVideoContentDAO().getById(video_id);
        if (currentVideoContent == null)
        {
            log.error("Video content is absent");
            return Constants.Navigation.VIDEO_CONTENT_LINK;
        }
        restoreFields();
        dirty = true;
        return Constants.Navigation.ADD_VIDEO_CONTENT_LINK;
    }

    public void deleteVideoContent(ActionEvent actionEvent)
    {
        Integer video_id = FacesHelper.getParameterAsInteger("delete_video_id");
        if (video_id != null)
        {
            VideoContentDAO videoContentDAO = getVideoContentDAO();
            videoContentDAO.delete(video_id);
            dirty = true;
        }
        else
        {
            log.error("video id is null");
        }
    }

    public List<SelectItem> getRegions()
    {
        if (Util.isEmpty(regions))
        {
            regions = new ArrayList<SelectItem>();
            List<Region> allRegions = getRegionDAO().getAll();
            for (Region region : allRegions)
            {
                SelectItem selectItem = new SelectItem(region.getId(), region.getName());
                regions.add(selectItem);
            }
        }
        return regions;
    }


    public void setRegions(List<SelectItem> regions)
    {
        this.regions = regions;
    }

    public List<SelectItem> getCategories()
    {
        if (Util.isEmpty(categories))
        {
            categories = new ArrayList<SelectItem>();
            List<Category> allCategories = getCategoryDAO().getAll();
            for (Category category : allCategories)
            {
                SelectItem selectItem = new SelectItem(category.getId(), category.getName());
                categories.add(selectItem);
            }
        }
        return categories;
    }

    public void setCategories(List<SelectItem> categories)
    {
        this.categories = categories;
    }

    public void setGroups(List<SelectItem> groups)
    {
        this.groups = groups;
    }


    public String getNewContentViewingCost()
    {
        return newContentViewingCost;
    }

    public void setNewContentViewingCost(String newContentViewingCost)
    {
        this.newContentViewingCost = newContentViewingCost;
    }

    public String getDescription()
    {
        return description;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    public DoubleNumberValidator getPaymentValidator()
    {
        return paymentValidator;
    }

    public void setPaymentValidator(DoubleNumberValidator paymentValidator)
    {
        this.paymentValidator = paymentValidator;
    }

    public DoubleNumberValidator getBudgetValidator()
    {
        return budgetValidator;
    }

    public void setBudgetValidator(DoubleNumberValidator budgetValidator)
    {
        this.budgetValidator = budgetValidator;
    }

    public List<Integer> getChosenRegions()
    {
        return chosenRegions;
    }

    public void setChosenRegions(List<String> chosenByUserRegions)
    {

        this.chosenRegions = new ArrayList<Integer>();
        for (String chooseOneRegion : chosenByUserRegions)
        {
            this.chosenRegions.add(Integer.parseInt(chooseOneRegion));
        }
    }

    public List<Integer> getChosenGroups()
    {
        return chosenGroups;
    }

    public void setChosenGroups(List<String> chosenByUserGroups)
    {
        this.chosenGroups = new ArrayList<Integer>();
        for (String chooseOneGroup : chosenByUserGroups)
        {
            this.chosenGroups.add(Integer.parseInt(chooseOneGroup));
        }
    }

    public String getFilterId()
    {
        return filterId;
    }

    public void setFilterId(String filterId)
    {
        this.filterId = filterId;
    }

    public String getFilterName()
    {
        return filterName;
    }

    public void setFilterName(String filterName)
    {
        this.filterName = filterName;
    }

    public String getFilterAdvertiser()
    {
        return filterAdvertiser;
    }

    public void setFilterAdvertiser(String filterAdvertiser)
    {
        this.filterAdvertiser = filterAdvertiser;
    }


    public String getSoundTrack()
    {
        return soundTrack;
    }

    public void setSoundTrack(String soundTrack)
    {
        this.soundTrack = soundTrack;
    }

    public List<Integer> getChosenFilterRegions()
    {
        return chosenFilterRegions;
    }

    public void setChosenFilterRegions(List<String> chosenByUserRegions)
    {
        chosenFilterRegions = new ArrayList<Integer>();
        for (String chosenRegion : chosenByUserRegions)
        {
            chosenFilterRegions.add(Integer.parseInt(chosenRegion));
        }
    }

    public List<Integer> getChosenFilterCategories()
    {
        return chosenFilterCategories;
    }

    public void setChosenFilterCategories(List<String> chosenByUserCategories)
    {
        chosenFilterCategories = new ArrayList<Integer>();
        for (String chosenCategorie : chosenByUserCategories)
        {
            chosenFilterCategories.add(Integer.parseInt(chosenCategorie));
        }
    }

    public Status getChosenStatus()
    {
        return chosenStatus;
    }

    public void setChosenStatus(Status chosenStatus)
    {
        this.chosenStatus = chosenStatus;
    }

    public String getRowCount()
    {
        rowCount = getVideoContentDAO().getAll().size();
        if (rowCount == null)
        {
            return "0";
        }
        return rowCount.toString();
    }

    public void setRowCount(Integer rowCount)
    {
        this.rowCount = rowCount;
    }

    public String getContentId()
    {
        return contentId;
    }

    public void setContentId(String contentId)
    {
        this.contentId = contentId;
    }

    public Integer getRows()
    {
        return rows;
    }

    public void setRows(Integer rows)
    {
        this.rows = rows;
    }

    public String getFrom()
    {
        return from;
    }

    public void setFrom(String from)
    {
        this.from = from;
    }

    public String getTo()
    {
        return to;
    }

    public void setTo(String to)
    {
        this.to = to;
    }
}
